"""
Flask工具箱主入口文件
提供多种日常办公工具
"""
from flask import Flask, render_template, redirect, url_for, session, request
from config import config
import os
import sys
import logging
from logging.handlers import TimedRotatingFileHandler
from datetime import datetime
import socket


def get_local_ip():
    """获取本机内网IP地址"""
    try:
        # 创建一个UDP socket
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        # 连接到一个公网地址（不会真的发送数据）
        s.connect(('8.8.8.8', 80))
        # 获取socket的本地地址
        local_ip = s.getsockname()[0]
        s.close()
        return local_ip
    except Exception:
        return '127.0.0.1'


def setup_logging(app):
    """配置日志系统"""
    # 确保日志目录存在
    log_folder = app.config['LOG_FOLDER']
    os.makedirs(log_folder, exist_ok=True)
    
    # 创建日志文件路径（按天生成）
    log_file = os.path.join(log_folder, f'app_{datetime.now().strftime("%Y%m%d")}.log')
    
    # 创建TimedRotatingFileHandler，每天午夜自动切换日志文件
    file_handler = TimedRotatingFileHandler(
        filename=log_file,
        when='midnight',  # 每天午夜切换
        interval=1,       # 间隔1天
        backupCount=90,   # 保留90天的日志
        encoding='utf-8'
    )
    
    # 设置日志文件名格式（添加日期后缀）
    file_handler.suffix = '%Y%m%d'
    
    # 设置日志格式（详细格式用于文件）
    file_formatter = logging.Formatter(
        app.config['LOG_FORMAT'],
        datefmt=app.config['LOG_DATE_FORMAT']
    )
    file_handler.setFormatter(file_formatter)
    
    # 设置日志级别
    log_level = getattr(logging, app.config['LOG_LEVEL'].upper(), logging.INFO)
    file_handler.setLevel(log_level)
    
    # 配置控制台输出（简洁格式）
    console_handler = logging.StreamHandler()
    console_formatter = logging.Formatter('%(message)s')  # 控制台只显示消息内容
    console_handler.setFormatter(console_formatter)
    console_handler.setLevel(log_level)
    
    # 配置Flask应用的logger
    app.logger.handlers.clear()  # 清除默认的handler
    app.logger.addHandler(file_handler)
    app.logger.addHandler(console_handler)
    app.logger.setLevel(log_level)
    app.logger.propagate = False  # 禁止向上传播，避免重复
    
    # 配置Werkzeug日志（Flask开发服务器的日志）
    werkzeug_logger = logging.getLogger('werkzeug')
    werkzeug_logger.handlers.clear()
    werkzeug_logger.addHandler(file_handler)
    # Werkzeug的日志不输出到控制台，保持Flask默认的简洁输出
    werkzeug_logger.setLevel(logging.WARNING)  # 只记录警告和错误
    werkzeug_logger.propagate = False


def create_app(config_name='default'):
    """应用工厂函数"""
    app = Flask(__name__)
    
    # 加载配置
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    
    # 配置日志系统
    setup_logging(app)
    
    # 初始化验证器
    from routes.auth import auth_bp, init_auth_verifier
    verifier = init_auth_verifier(app)
    app.verifier = verifier  # 将验证器保存到app对象
    
    # 注册蓝图（添加应用前缀）
    from routes.main import main_bp
    from routes.tools import tools_bp
    
    app_prefix = app.config.get('APPLICATION_ROOT', '')
    app.register_blueprint(auth_bp, url_prefix=f'{app_prefix}/auth')
    app.register_blueprint(main_bp, url_prefix=app_prefix)
    app.register_blueprint(tools_bp, url_prefix=f'{app_prefix}/tools')
    
    # 请求前验证
    @app.before_request
    def check_verification():
        """检查系统验证状态"""
        app_prefix = app.config.get('APPLICATION_ROOT', '')
        # 排除验证相关的路由和静态文件
        if request.path.startswith(f'{app_prefix}/auth/') or request.path.startswith('/static/'):
            return None
        
        # 检查全局验证状态
        status = verifier.check_verification_status()
        
        # 如果系统未解锁，重定向到验证页面
        if not status['valid']:
            return redirect(url_for('auth.verify_page'))
        
        return None
    
    # 根路径重定向到应用前缀路径
    @app.route('/')
    def root_redirect():
        """将根路径重定向到应用前缀路径"""
        app_prefix = app.config.get('APPLICATION_ROOT', '')
        if app_prefix:
            return redirect(app_prefix + '/')
        return redirect(url_for('main.index'))
    
    # 注册全局模板变量
    @app.context_processor
    def inject_developer_info():
        """向所有模板注入开发者信息"""
        return {
            'developer_name': app.config.get('DEVELOPER_NAME', '开发者'),
            'developer_wechat': app.config.get('DEVELOPER_WECHAT', ''),
            'config': app.config,
            'app_prefix': app.config.get('APPLICATION_ROOT', '')
        }
    
    # 错误处理
    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('404.html'), 404
    
    @app.errorhandler(500)
    def internal_server_error(e):
        return render_template('500.html'), 500
    
    return app


if __name__ == '__main__':
    # 创建应用实例
    app = create_app(os.getenv('FLASK_ENV', 'development'))
    
    # 运行应用
    developer_name = app.config.get('DEVELOPER_NAME', '开发者')
    local_ip = get_local_ip()
    port = 5000
    
    app_prefix = app.config.get('APPLICATION_ROOT', '')
    python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
    print("\n" + "=" * 60)
    print(f"  🚀 {developer_name}的JYB工具箱")
    print(f"  🐍 Python版本: {python_version}")
    print(f"  📁 日志目录: {app.config['LOG_FOLDER']}")
    print(f"  🌐 本地访问: http://127.0.0.1:{port}{app_prefix}/")
    print(f"  🌍 内网访问: http://{local_ip}:{port}{app_prefix}/")
    print("=" * 60 + "\n")
    
    app.run(
        host='0.0.0.0',
        port=port,
        debug=True
    )

